cmake_minimum_required(VERSION 3.10)
project(avr-libstdcxx VERSION 15.2.0)

set(ARCH -mmcu=avr6)
include_directories(inc inc/avr inc/backward)

# supc++
add_library(
  avr-libsupc++ OBJECT
  src/libsupc++/array_type_info.cc
  src/libsupc++/atexit_arm.cc
  src/libsupc++/atexit_thread.cc
  src/libsupc++/bad_alloc.cc
  src/libsupc++/bad_array_length.cc
  src/libsupc++/bad_array_new.cc
  src/libsupc++/bad_cast.cc
  src/libsupc++/bad_typeid.cc
  src/libsupc++/class_type_info.cc
  src/libsupc++/del_op.cc
  src/libsupc++/del_ops.cc
  src/libsupc++/del_opnt.cc
  src/libsupc++/del_opv.cc
  src/libsupc++/del_opvs.cc
  src/libsupc++/del_opvnt.cc
  src/libsupc++/dyncast.cc
  src/libsupc++/eh_alloc.cc
  src/libsupc++/eh_arm.cc
  src/libsupc++/eh_aux_runtime.cc
  src/libsupc++/eh_call.cc
  src/libsupc++/eh_catch.cc
  src/libsupc++/eh_exception.cc
  src/libsupc++/eh_globals.cc
  src/libsupc++/eh_personality.cc
  src/libsupc++/eh_ptr.cc
  src/libsupc++/eh_term_handler.cc
  src/libsupc++/eh_terminate.cc
  src/libsupc++/eh_tm.cc
  src/libsupc++/eh_throw.cc
  src/libsupc++/eh_type.cc
  src/libsupc++/eh_unex_handler.cc
  src/libsupc++/enum_type_info.cc
  src/libsupc++/function_type_info.cc
  src/libsupc++/fundamental_type_info.cc
  src/libsupc++/guard.cc
  src/libsupc++/guard_error.cc
  src/libsupc++/hash_bytes.cc
  src/libsupc++/nested_exception.cc
  src/libsupc++/new_handler.cc
  src/libsupc++/new_op.cc
  src/libsupc++/new_opnt.cc
  src/libsupc++/new_opv.cc
  src/libsupc++/new_opvnt.cc
  src/libsupc++/new_opa.cc
  src/libsupc++/new_opant.cc
  src/libsupc++/new_opva.cc
  src/libsupc++/new_opvant.cc
  src/libsupc++/del_opa.cc
  src/libsupc++/del_opant.cc
  src/libsupc++/del_opsa.cc
  src/libsupc++/del_opva.cc
  src/libsupc++/del_opvant.cc
  src/libsupc++/del_opvsa.cc
  src/libsupc++/pbase_type_info.cc
  src/libsupc++/pmem_type_info.cc
  src/libsupc++/pointer_type_info.cc
  src/libsupc++/pure.cc
  src/libsupc++/si_class_type_info.cc
  src/libsupc++/tinfo.cc
  src/libsupc++/tinfo2.cc
  src/libsupc++/vec.cc
  src/libsupc++/vmi_class_type_info.cc
  src/libsupc++/vterminate.cc
)
target_compile_options(avr-libsupc++ PUBLIC ${ARCH} -ffunction-sections -fdata-sections -Wall -Wextra -Wwrite-strings -Wcast-qual -Wabi=19 -fdiagnostics-show-location=once)
target_include_directories(avr-libsupc++ PUBLIC libsupc++ .)

# demangle
add_library(avr-libsupc++-demangle OBJECT src/libsupc++/cp-demangle.c)
target_include_directories(avr-libsupc++-demangle PUBLIC libsupc++ .)
target_compile_options(avr-libsupc++-demangle PUBLIC ${ARCH} -ffunction-sections -fdata-sections)
target_compile_definitions(avr-libsupc++-demangle PUBLIC -DHAVE_CONFIG_H -DIN_GLIBCPP_V3)

#c++98
add_library(
  avr-libstdcxx-c++98 OBJECT
  src/c++98/bitmap_allocator.cc
  src/c++98/pool_allocator.cc
  src/c++98/mt_allocator.cc
  src/c++98/codecvt.cc
  src/c++98/complex_io.cc
  src/c++98/globals_io.cc
  src/c++98/hash_tr1.cc
  src/c++98/hashtable_tr1.cc
  src/c++98/ios_failure.cc
  src/c++98/ios_init.cc
  src/c++98/ios_locale.cc
  src/c++98/list.cc
  src/c++98/list-aux.cc
  src/c++98/list-aux-2.cc
  src/c++98/list_associated.cc
  src/c++98/list_associated-2.cc
  src/c++98/locale.cc
  src/c++98/locale_facets.cc
  src/c++98/math_stubs_float.cc
  src/c++98/math_stubs_long_double.cc
  src/c++98/stdexcept.cc
  src/c++98/strstream.cc
  src/c++98/tree.cc
  src/c++98/istream.cc
  src/c++98/istream-string.cc
  src/c++98/streambuf.cc
  src/c++98/valarray.cc
  src/c++98/cow-istream-string.cc
  src/c++98/allocator-inst.cc
  src/c++98/concept-inst.cc
  src/c++98/ext-inst.cc
  src/c++98/misc-inst.cc
  src/c++98/parallel_settings.cc
)
target_compile_definitions(avr-libstdcxx-c++98 PUBLIC )
target_compile_options(avr-libstdcxx-c++98 PUBLIC ${ARCH} -std=gnu++98 -ffunction-sections -fdata-sections -Wall -Wextra -Wwrite-strings -Wcast-qual -Wabi=19 -fdiagnostics-show-location=once)
target_include_directories(avr-libstdcxx-c++98 PUBLIC src/c++98)

#c++11
add_library(
  avr-libstdcxx-c++11 OBJECT
  src/c++11/limits.cc
  src/c++11/placeholders.cc
  src/c++11/assert_fail.cc
  src/c++11/chrono.cc
  src/c++11/codecvt.cc
  src/c++11/condition_variable.cc
  src/c++11/cow-stdexcept.cc
  src/c++11/cow-system_error.cc
  src/c++11/ctype.cc
  src/c++11/debug.cc
  src/c++11/functexcept.cc
  src/c++11/functional.cc
  src/c++11/futex.cc
  src/c++11/future.cc
  src/c++11/hash_c++0x.cc
  src/c++11/hashtable_c++0x.cc
  src/c++11/ios.cc
  src/c++11/ios_errcat.cc
  src/c++11/locale_init.cc
  src/c++11/localename.cc
  src/c++11/mutex.cc
  src/c++11/random.cc
  src/c++11/regex.cc
  src/c++11/shared_ptr.cc
  src/c++11/snprintf_lite.cc
  src/c++11/system_error.cc
  src/c++11/thread.cc
  src/c++11/cow-locale_init.cc
  src/c++11/cow-shim_facets.cc
  src/c++11/cxx11-hash_tr1.cc
  src/c++11/cxx11-shim_facets.cc
  src/c++11/cxx11-stdexcept.cc
  src/c++11/cow-fstream-inst.cc
  src/c++11/cow-sstream-inst.cc
  src/c++11/cow-string-inst.cc
  src/c++11/cow-string-io-inst.cc
  src/c++11/cow-wstring-inst.cc
  src/c++11/cow-wstring-io-inst.cc
  src/c++11/cxx11-locale-inst.cc
  src/c++11/cxx11-wlocale-inst.cc
  src/c++11/sso_string.cc
  src/c++11/ext11-inst.cc
  src/c++11/fstream-inst.cc
  src/c++11/ios-inst.cc
  src/c++11/iostream-inst.cc
  src/c++11/istream-inst.cc
  src/c++11/locale-inst.cc
  src/c++11/ostream-inst.cc
  src/c++11/sstream-inst.cc
  src/c++11/streambuf-inst.cc
  src/c++11/string-inst.cc
  src/c++11/string-io-inst.cc
  src/c++11/wlocale-inst.cc
  src/c++11/wstring-inst.cc
  src/c++11/wstring-io-inst.cc
  src/c++11/compatibility-atomic-c++0x.cc
  src/c++11/compatibility-c++0x.cc
  src/c++11/compatibility-chrono.cc
  src/c++11/compatibility-condvar.cc
  src/c++11/compatibility-thread-c++0x.cc
)
target_compile_options(avr-libstdcxx-c++11 PUBLIC ${ARCH} -std=gnu++11 -ffunction-sections -fdata-sections -Wall -Wextra -Wwrite-strings -Wcast-qual -Wabi=19 -fdiagnostics-show-location=once)
target_include_directories(avr-libstdcxx-c++11 PUBLIC inc/bits/ src/c++11/)

# c++17
add_library(
  avr-libstdcxx-c++17 OBJECT
  src/c++17/floating_from_chars.cc
  src/c++17/floating_to_chars.cc
  src/c++17/fs_dir.cc
  src/c++17/fs_ops.cc
  src/c++17/fs_path.cc
  src/c++17/memory_resource.cc
  src/c++17/cow-fs_dir.cc
  src/c++17/cow-fs_ops.cc
  src/c++17/cow-fs_path.cc
  src/c++17/ostream-inst.cc
  src/c++17/string-inst.cc
  src/c++17/cow-string-inst.cc
)
target_compile_options(avr-libstdcxx-c++17 PUBLIC ${ARCH} -std=gnu++17 -ffunction-sections -fdata-sections -Wall -Wextra -Wwrite-strings -Wcast-qual -Wabi=19 -fdiagnostics-show-location=once)
target_include_directories(avr-libstdcxx-c++17 PUBLIC src/c++17)

# c++20
add_library(
  avr-libstdcxx-c++20 OBJECT
  src/c++20/tzdb.cc
  src/c++20/format.cc
  src/c++20/sstream-inst.cc
)
target_compile_options(avr-libstdcxx-c++20 PUBLIC ${ARCH} -std=gnu++20 -ffunction-sections -fdata-sections -Wall -Wextra -Wwrite-strings -Wcast-qual -Wabi=19 -fdiagnostics-show-location=once)
target_include_directories(avr-libstdcxx-c++20 PUBLIC src/c++20)

# c++23
add_library(
  avr-libstdcxx-c++23 OBJECT
  src/c++23/stacktrace.cc
  src/c++23/print.cc
)
target_compile_options(avr-libstdcxx-c++23 PUBLIC ${ARCH} -std=gnu++23 -ffunction-sections -fdata-sections -Wall -Wextra -Wwrite-strings -Wcast-qual -Wabi=19 -fdiagnostics-show-location=once)
target_include_directories(avr-libstdcxx-c++23 PUBLIC src/c++23)

# C++26
add_library(
  avr-libstdcxx-c++26 OBJECT
  src/c++26/text_encoding.cc
)
target_compile_options(avr-libstdcxx-c++26 PUBLIC ${ARCH} -std=gnu++26 -ffunction-sections -fdata-sections -Wall -Wextra -Wwrite-strings -Wcast-qual -Wabi=19 -fdiagnostics-show-location=once)
target_include_directories(avr-libstdcxx-c++26 PUBLIC src/c++26)

# experimental
add_library(
  avr-libstdcxx-experimental OBJECT
  src/experimental/contract.cc
)
target_compile_options(avr-libstdcxx-experimental PUBLIC ${ARCH} -std=gnu++17 -nostdinc++ -ffunction-sections -fdata-sections -Wall -Wextra -Wwrite-strings -Wcast-qual -Wabi=19 -fdiagnostics-show-location=once)
target_include_directories(avr-libstdcxx-experimental PUBLIC src/experimental)

# libstdc++
add_library(
  avr-libstdcxx STATIC
  $<TARGET_OBJECTS:avr-libsupc++>
  $<TARGET_OBJECTS:avr-libstdcxx-c++98>
  $<TARGET_OBJECTS:avr-libstdcxx-c++11>
  $<TARGET_OBJECTS:avr-libstdcxx-c++17>
  $<TARGET_OBJECTS:avr-libstdcxx-c++20>
  $<TARGET_OBJECTS:avr-libstdcxx-c++23>
  $<TARGET_OBJECTS:avr-libstdcxx-c++26>
  $<TARGET_OBJECTS:avr-libstdcxx-experimental>
)

# test
add_executable(container_test test/container.cpp)
target_compile_options(container_test PUBLIC -mmcu=atmega2560 -std=gnu++23 -ffunction-sections -fdata-sections)
target_include_directories(container_test PUBLIC inc inc/avr inc/backward)
target_link_libraries(container_test avr-libstdcxx)
target_link_options(container_test PUBLIC -mmcu=atmega2560 -Wl,--gc-sections )
